package com.hugang.juc.communication;

/**
 * 题目：两个线程，可以操作初始值为零的一个变量，实现一个线程对该变量加1，一个线程对变量减1，实现交替，来10轮
 * 1、高内聚低耦合前提下，线程操作资源类
 * 2、判定 - 干活 - 通知
 * 3、多线程交互中，必须要防止多线程的虚假唤醒，即判断使用while，不使用if
 *
 * @author hg
 * @date 2020/8/19 10:33
 */
public class ThreadWaitNotifyDemo {

    public static void main(String[] args) {
        Number number = new Number();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    number.add();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程1").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    number.sub();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程2").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    number.add();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程3").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    number.sub();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程4").start();
    }


    /**
     * 资源类
     */
    static class Number {
        private int number;

        public synchronized void add() throws InterruptedException {
            while (number > 0) {
                wait();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + "---> number：" + number);
            notifyAll();
        }

        public synchronized void sub() throws InterruptedException {
            while (number < 1) {
                wait();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "---> number：" + number);
            notifyAll();
        }
    }
}
